package main;

import java.io.IOException;
import java.util.ArrayList;

import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSpan;
import com.gargoylesoftware.htmlunit.html.HtmlTable;
import com.gargoylesoftware.htmlunit.html.HtmlTableRow;

public class InstituitionDetailsActor {

	private String courseTableXpath = "//table[@id='ctl00_cphDefaultPage_tabContainer_sheetCourseList_courseList_gridSearchResults']";
	private Writer instituitionDetailsWriter;

	private HtmlPage listPage;
	private String state;
	private InstituitionDetails instituitionDetails;
	private ArrayList<CourseOffered> courseList;

	public InstituitionDetailsActor(Writer instituitionDetailsWriter, HtmlPage listPage, String state) {
		this.instituitionDetailsWriter = instituitionDetailsWriter;
		this.state = state;
		this.listPage = listPage;
	}

	public void generateInfo() {

		
		this.instituitionDetails = new InstituitionDetails(this.listPage, state);
		this.courseList = this.getCoursesOfferd();
		this.writeInfo();
	}

	// escreve a linha do curso no arquivo
	private void writeInfo() {
		for (int i = 0; i < this.courseList.size(); i++) {
			CourseOffered course = this.courseList.get(i);

			String instiInfo = this.instituitionDetails.getDetails();
			this.instituitionDetailsWriter.Write(instiInfo, course.getName(), course.getLevel(), course.getDuration(),
					course.getName() + " - " + this.instituitionDetails.getName() + " - " + course.getLevel() + " - " + course.getDuration());
			System.out.println(instiInfo + "," + course.getName() + "," + course.getLevel() + "," + course.getDuration() + "," + course.getName() + " - " + this.instituitionDetails.getName() + " - "
					+ course.getLevel() + " - " + course.getDuration());
		}

	}

	private HtmlTable getCoursesTable(HtmlPage listPage) {
		if (listPage.getByXPath(courseTableXpath).size() == 0) return null;
		return (HtmlTable) listPage.getByXPath(courseTableXpath).get(0);
	}

	private ArrayList<CourseOffered> getCoursesOfferd() {
		ArrayList<CourseOffered> list = new ArrayList<CourseOffered>();
		
		HtmlPage page = getCourseListPage(this.listPage,1,0);
		
		// pega a tabela de cursos oferecidos na aba
		HtmlTable courseTable = getCoursesTable(page);
		
		// caso nao econtre cursos retona uma lista com um curso com detalhes vazios ( para poder imprimir pelo menosos dados da instituicao)
		if (courseTable == null) return this.returnNocourses();

		// pega o numero de paginas
		int pages = getNumberPages(courseTable);

		// para cada pagina pega os cursos
		for (int pageNumber = 1; pageNumber <= pages; pageNumber++) {

			for (int i = 1; i < courseTable.getRows().size(); i++) {
				
				if(!this.isGridRow(courseTable.getRows().get(i)))//XXX quanto estiver lendo a ultima linha tem que ignorar o gridRow
				list.add(new CourseOffered(courseTable.getRows().get(i)));
			}
			page = getCourseListPage(this.listPage,pageNumber +1,pages);
			courseTable = getCoursesTable(page);
		}
		return list;
	}

	private ArrayList<CourseOffered> returnNocourses() {
		ArrayList<CourseOffered> result = new ArrayList<CourseOffered>();
		result.add(CourseOffered.getNoCourses());
		return result;
	}

	private boolean isGridRow(HtmlTableRow htmlTableRow) {
		if ( htmlTableRow.getAttribute("class").equals("gridPager")) return true;
		return false;
	}

	private HtmlPage getCourseListPage(HtmlPage listPage, int pageNumber, int total) {
		if (pageNumber >= total || pageNumber == 1 )return listPage;
		
		return this.clickLink(this.getLinkToNextPage(listPage,pageNumber));
		
		
		
	}

	private int getNumberPages(HtmlTable courseTable) {
		if (courseTable.getRows().size() < 2)
			return 1;

		if (courseTable.getRow(courseTable.getRows().size() - 1).getAttribute("class").equals("gridPager")) {
			HtmlTableRow row = courseTable.getRow(courseTable.getRows().size() - 1);
			HtmlTable table = getTableGrid(row);

			return this.getPagesAmount(table);
		}
		;

		return 1;
	}

	private int getPagesAmount(HtmlTable table) {
		HtmlSpan span = (HtmlSpan) table.getRow(0).getFirstChild().getFirstChild();

		String pageAmount = span.getTextContent().subSequence(9, span.getTextContent().indexOf("(")).toString().trim();
		return Integer.parseInt(pageAmount);
	}

	private HtmlTable getTableGrid(HtmlTableRow row) {

		return (HtmlTable) row.getFirstChild().getFirstChild();
	}
	
	private HtmlAnchor getLinkToNextPage(HtmlPage page, int pageNumber)
	{
		HtmlAnchor nextPageLink = (HtmlAnchor) page.createElement("a");
		nextPageLink.setAttribute("href", getNextPageJavaScriptCode(pageNumber));
		return nextPageLink;
		
	}
	
	private String getNextPageJavaScriptCode(int pagenumber) {
		String base = "javascript:__doPostBack('ctl00$cphDefaultPage$tabContainer$sheetCourseList$courseList$gridSearchResults','#Page$')";

		String result = base.replace("#Page$", "Page$" + pagenumber);
		return result;
	}
	
	private HtmlPage clickLink(HtmlAnchor nextPageLink) {
		HtmlPage result = null;

		try {
			result = nextPageLink.click();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return result;
	}

}
